﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Net;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using Common;
namespace Host
{
    public delegate string HttpInterface(HttpListenerContext context);

    public class HttpServerComponents : IComponents
    {
        private Thread _thread = null;
        private bool _runing = false;
        private RouteData<HttpInterface> _routedata = new RouteData<HttpInterface>();

        public HttpServerComponents()
        {
        }

        private string _host_name = "localhost";

        public string HostName
        {
            get { return _host_name; }
            set { _host_name = value; }
        }

        private int _port = 8856;

        public int Port
        {
            get { return _port; }
            set { _port = value; }
        }

        public RouteData<HttpInterface> RouteData { get { return _routedata; } }

        private string GetRouteKey(string rawurl)
        {
            if (string.IsNullOrEmpty(rawurl))
                return string.Empty;

            var index = rawurl.IndexOf('?');
            if (index != -1)
            {
                rawurl = rawurl.Substring(0, index);
            }

            return rawurl.TrimStart('/').TrimEnd('/');
        }

        public override void OnEnter()
        {
            base.OnEnter();

            _runing = true;
            _thread = new Thread(() =>
            {
                HttpListener listener = new HttpListener();
                listener.Prefixes.Add(string.Format("http://{0}:{1}/", _host_name, _port));
                listener.Start();

                while (_runing)
                {
                    HttpListenerContext context = listener.GetContext();
                    HttpListenerRequest request = context.Request;
                    HttpListenerResponse response = context.Response;

                    Console.WriteLine("new Request" + request.RawUrl);

                    new Thread(() =>
                    {
                        var route_key = GetRouteKey(request.RawUrl);
                        var handle = RouteData.FindValue(route_key);

                        string responseString = string.Empty;

                        if (handle != null)
                        {
                            try
                            {
                                responseString = handle(context);
                            }
                            catch (Exception ex)
                            {
                                responseString = ex.Message;
                            }
                        }
                        else
                        {
                            responseString = "Not Find Handle";
                        }

                        byte[] buffer = request.ContentEncoding.GetBytes(responseString);
                        response.ContentLength64 = buffer.Length;
                        System.IO.Stream output = response.OutputStream;
                        output.Write(buffer, 0, buffer.Length);
                        output.Close();
                    }).Start();
                }

                listener.Stop();
            });
            _thread.IsBackground = true;
            _thread.Start();
        }

        public override void OnExit()
        {
            base.OnExit();

            _runing = false;
            while (_thread.ThreadState == ThreadState.Running)
                ;
        }
    }
}
